/**
 * 图片爬虫
 * */
const puppeteer = require('puppeteer')
const fs = require('fs')
const path = require('path')
const https = require('https')
const http = require('http')

const autoScroll = async page => {
  console.log('scroll page')
  await page.evaluate(() => {
    return new Promise((resolve, reject) => {
      let totalHeight = 0,
        distance = 100

      let timer = setInterval(() => {
        let docScrollHeight =
          document.body.scrollHeight || document.documentElement.scrollHeight
        window.scrollBy(0, distance)
        totalHeight += distance

        // 假设滚动到1000px就不去加载了
        if (totalHeight >= 1000) {
          clearInterval(timer)
          resolve()
        }
      }, 200)
    })
  })
}

const reptile = async () => {
  const browser = await puppeteer.launch()
  const page = await browser.newPage()
  await page.goto('https://image.baidu.com')
  await page.focus('#kw')
  await page.keyboard.sendCharacter('猫咪')
  await page.click('.s_search')

  page.on('load', async () => {
    await autoScroll(page) // 先拉动页面滚动条
    const result = await page.evaluate(() => {
      let elems = document.querySelectorAll('img.main_img')
      const srcs = Array.prototype.map.call(elems, img => img.src)
      return srcs
    })

    storeData(result)
    await loadImg(result)
    await browser.close()
  })
}

/**
 * 存储数据
 * */

function storeData(res) {
  fs.writeFile(`${__dirname}/data/images.json`, JSON.stringify(res), err => {
    if (err) throw err
    console.log('file has saved')
  })
}

/**
 * 下载图片
 */
async function loadImg(srcs) {
  for (let i = 0, len = srcs.length; i < len; i++) {
    if (/^http/.test(srcs[i])) {
      let mod = /^https:/.test(srcs[i]) ? https : http
      mod.get(srcs[i], res => {
        let ext = path.extname(srcs[i])
        let filePath = path.join(`${__dirname}/data/images/`, `${i}${ext}`)
        let writeStream = fs.createWriteStream(filePath)
        res
          .pipe(writeStream)
          .on('finish', () => {
            console.log(filePath + '写入成功')
          })
          .on('error', err => {
            throw err
          })
      })
    } else {
      let match = /^data:(.*?);base64,(.+)$/.exec(srcs[i])
      try {
        let ext = match[1].split('/')[1].replace('jpeg', 'jpg')
        let filePath = path.join(`${__dirname}/data/images/`, `${i}.${ext}`)
        fs.writeFile(filePath, match[2], 'base64', err => {
          if (err) throw err
          console.log(filePath + '写入成功')
        })
      } catch (err) {
        console.log(err)
      }
    }
  }
}

reptile()
